﻿using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using System.Diagnostics;
using System.Reflection;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace SelfDoc
{
    static class SelfDocProgram
    {

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        private static extern IntPtr FindResource(IntPtr handle, String pFileName, String type);

         [DllImport("kernel32", CharSet = CharSet.Unicode)]
        private static extern uint SizeofResource(IntPtr an, IntPtr resourceHandle );

         [DllImport("kernel32.dll", SetLastError = true)]

         public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            string strPath = Path.Combine(
               Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
             , "elookinto") + "\\";
            //strPath = @"c:\temp\elookinto\";

            String filename = Assembly.GetExecutingAssembly().Location;

             
            IntPtr handle = FindResource((IntPtr)0, "FILE.ZIP", "FILE");
            if (handle.ToInt32() == 0)
            {
                MessageBox.Show("Not a valid document");
                //Console.WriteLine("Not a valid document");
                return;
            }
            long size = SizeofResource((IntPtr)0, handle);
            IntPtr pBeginning = LoadResource((IntPtr)0, handle);
            byte[] data  = new byte[size];
            Marshal.Copy(pBeginning, data, 0, data.Length);

            if (!Directory.Exists(strPath))
            {
                Directory.CreateDirectory(strPath);
            }
            String dataDir = strPath + @"data\";
            String fileName = dataDir + data.GetHashCode() + ".zip";
            if (!Directory.Exists(dataDir))
            {
                Directory.CreateDirectory(dataDir);
            }
            using (StreamWriter fs = new StreamWriter(fileName))
            {

                fs.Write(System.Convert.ToBase64String(data));
            }

            String binDir = strPath + @"bin\1.0\";
            if (!Directory.Exists(binDir))
            {
               
#if INTERNET
                String url = "http://www.elookinto.com/Bin.zip";
                WebClient wc = getClient(url);
                if (wc == null)
                {
                    MessageBox.Show("You may not have no internet connection or adjust your internet proxy");
                    return;
                }
                byte[] bb = wc.DownloadData(url);

#else

                byte[] bb = global::SelfDoc.Properties.Resources.Bin;
#endif
                Directory.CreateDirectory(binDir);
                MemoryStream ms0 = new MemoryStream(bb);
                using (ZipInputStream zis = new ZipInputStream(ms0))
                {
                    ZipEntry ze = null;
                    MemoryStream tms = null;
                    FileStream fs = null;
                    while ((ze = zis.GetNextEntry()) != null)
                    {
                        try
                        {
                            fs = new FileStream(binDir + ze.Name, FileMode.CreateNew);
                            byte[] buffer = new byte[zis.Length];
                            zis.Read(buffer, 0, (int)zis.Length);

                            tms = new MemoryStream(buffer);
                            tms.CopyTo(fs);

                        }

                        finally
                        {
                            if (tms != null)
                                tms.Close();
                            if (fs != null)
                                fs.Close();
                        }

                    }

                }
                registerDLL(binDir + "CsharpWindowsActiveX.dll");

            }

            ProcessStartInfo startInfo = new ProcessStartInfo();
            //startInfo.CreateNoWindow = false;
            //startInfo.UseShellExecute = false;
            startInfo.FileName = binDir + "selfviewer.exe";
            //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.Arguments = "\"" + fileName + "\""; ;
            try
            {
                // Start the process with the info we specified.
                // Call WaitForExit and then the using statement will close.
                using (Process exeProcess = Process.Start(startInfo))
                {
                    exeProcess.WaitForExit();
                }
                //File.Delete(startInfo.FileName);
                File.Delete(fileName);
                //Directory.Delete(binDir,true);
            }
            catch
            {
                // Log error.
            }

        }

        public static void registerDLL(string dllPath)
        {
            try
            {
                //'/s' : indicates regsvr32.exe to run silently.
                string fileinfo = "/s" + " " + "\"" + dllPath + "\"";

                Process reg = new Process();
                reg.StartInfo.FileName = "regsvr32.exe";
                reg.StartInfo.Arguments = fileinfo;
                reg.StartInfo.UseShellExecute = false;
                reg.StartInfo.CreateNoWindow = true;
                reg.StartInfo.RedirectStandardOutput = true;
                reg.Start();
                reg.WaitForExit();
                reg.Close();
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }
        }

#if INTERNET

        private static WebClient getClient(String url)
        {
            bool connected = false;
            try
            {
                Org.Mentalis.Network.Url oUrl = new Org.Mentalis.Network.Url(url);
                Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                IAsyncResult re = clientSock.BeginConnect(oUrl.Host, oUrl.Port, null, null);
                connected = re.AsyncWaitHandle.WaitOne(5000, true);
                WebClient wc = new WebClient();
                if (!connected)
                {
                    IWebProxy proxy = WebRequest.GetSystemWebProxy();
                    Uri request = new Uri(url);
                    Uri requestProxy = proxy.GetProxy(request);
                    if (request != requestProxy)
                    {
                      
                        wc.Proxy = proxy;
                        wc.UseDefaultCredentials = true;
                        connected = true;
                    }

                }
                clientSock.Close();
                if (connected) return wc;
            }
            catch (Exception e)
            {

            }
            return null;
        }
#endif
    }
}

